const express = require('express');
const bcrypt = require('bcryptjs')
const mongoose = require("mongoose")
const path = require("path")
const fs = require("fs")
const router = express.Router();
const multiparty = require('multiparty')  // 处理表单提交的数据
const { auth, isLogin } = require('../../utils/auth')
const {UPLOADPATH,LOCAL_IMG_URL} = require('../../config')
const {importExcel} = require('../../utils/exportExcel')

const userController = require('../../controllers/userController') 
const storeController = require('../../controllers/storeController') 
const productController = require('../../controllers/productController')
const customController = require('../../controllers/customController') 
const serieController = require('../../controllers/serieController')
const orderController = require('../../controllers/orderController') 
const cashbackController = require('../../controllers/cashbackController') 

const Token = require('../../utils/token')


const {backSuc,backErr,resolveParams,getUnitVal} = require('../../utils/common')


// 后台系统登录
router.post('/login',async (req,res)=>{
    const {userName,password} = req.body
    // 登录处理
    let params = {}
    params['$or'] = [ //多条件模糊查询，数组
        { userName},
        { phone:userName}
    ]
    const cur_user = await userController.findOne(params)
    if(!cur_user){ 
       return backErr(res,'该用户不存在')
    }
    if(cur_user.status!=1){
        return backErr(res,'账号已被禁用',4000)
    }

    //检查密码是否匹配
    const pwdMatchFlag = bcrypt.compareSync(password, cur_user.password);
    if(pwdMatchFlag){  
      const token = new Token({id:cur_user._id+'###'+cur_user.type}) //以用户id和用户类型type生成token（'###'为id与type分隔符）
      const tokenData = await token.createToken()
      if(tokenData){
        let data = JSON.parse(JSON.stringify(cur_user))
        data.token = tokenData
        delete data.password
        backSuc(res,data)
      } 
    }else{        
      backErr(res,'密码错误',1001)
    }
})

// 修改后台管理账户登录密码
router.post('/admin/password/update',async (req,res)=>{
  const {id,oldPassword,newPassword} = req.body
  // 登录处理
  const cur_company = await userController.findOne({_id:id})
  if(!cur_company){ 
     return backErr(res,'该用户不存在')
  }
  if(cur_company.status!=1){
      return backErr(res,'账号已被禁用',4000)
  }

  //检查密码是否匹配
  const pwdMatchFlag = bcrypt.compareSync(oldPassword, cur_company.password);
  if(pwdMatchFlag){ // 原密码匹配
    // 密码加密存储
    let password = bcrypt.hashSync(newPassword,10)
    const rt = await userController.updateById(id,{password})
    if(!rt) return backErr(res,'修改失败')
    backSuc(res,rt)
  }else{        
    backErr(res,'原密码错误',1001)
  }
})

// 用户列表
router.post('/user-list',async (req,res)=>{
  const {params,page} = resolveParams(req.body) // 解析参数
  const sort = {createTime:-1}
  if(req.body.keyword){
      delete params.keyword
      params['$or'] = [ //多条件模糊查询，数组
          { name: { $regex: req.body.keyword, $options: 'i' } },
          { userName: { $regex: req.body.keyword, $options: 'i' } }
      ]
  }
  const rt = await userController.getList({params,page,sort})
  if(!rt) return backErr(res,'获取数据失败')
  backSuc(res,rt)
})

// **********************门店管理 start********************************************
// 门店列表
router.post('/store-list',async (req,res)=>{
  // const {params,page} = resolveParams(req.body) // 解析参数
  // const sort = {createTime:-1}
  // if(req.body.name){
  //     delete params.name
  //     params['$or'] = [ //多条件模糊查询，数组
  //         { name: { $regex: req.body.name, $options: 'i' } }
  //     ]
  // }
  // const rt = await storeController.getList({params,page,sort})
  // if(!rt) return backErr(res,'获取数据失败')
  // backSuc(res,rt)
  const {params,page} = resolveParams(req.body) // 解析参数
  const sort = {createTime:-1}

  if(req.body.name){
      delete params.name
      params['$or'] = [ //多条件模糊查询，数组
          { name: { $regex: req.body.name, $options: 'i' } }
      ]
  }
  let pm = [
      {
          // $lookup:{
          //     from: 'cashbacks',// 关联返款表
          //     localField: "_id",//本表需要关联的字段
          //     foreignField: "storeId",//被连接表需要关联的字段
          //     as: "cashbackData"//查询出的结果集别名
          // }
          $lookup:{
            from: 'cashbacks',// 关联返款表
            let:{"store_id":"$_id"},  // 相当于设置一个变量store_id，且值为左表（即主表，这里是stores）的_id
            as: "cashbackData",//查询出的结果集别名
            pipeline:[
              {
                    $match:{
                        $expr:{
                            $and:[
                                {$eq: ["$storeId","$$store_id" ]}, // 左表字段需要加前加$$，右表字段前需要加$
                                {$eq: ["$useStatus",1]}
                            ]
                        }
                    }
                } 
            ] 
          },
      },
      {
          $unwind: {
              path:'$cashbackData',// 转化为对象存储
              preserveNullAndEmptyArrays: true // 确保了即使关联未找到子文档，父文档也会出现在结果中
          }
      }, 
      {
        $lookup:{
          from: 'orders',// 关联顶订单表
          let:{"store_id":"$_id",'cashback_id':"$cashbackData._id"},  // 相当于设置一个变量store_id，且值为左表（即主表，这里是stores）的_id
          as: "ordersList",//查询出的结果集别名
          pipeline:[
            {
                  $match:{
                      $expr:{
                          $and:[
                              {$eq: ["$storeId","$$store_id" ]}, // 左表字段需要加前加$$，右表字段前需要加$
                              {$eq: ["$cashbackId","$$cashback_id"]},
                              {$gt: ["$backMoney",0]}, // backMoney要大于0
                          ]
                      }
                  }
              } 
          ] 
        },
    },
    {
        $match:params
    }
  ]
  const rt = await storeController.getList2(pm,page,sort)
  if(!rt) return backErr(res,'获取数据失败')
  backSuc(res,rt)
})

// 添加门店
router.post('/store-add',async (req,res)=>{
  const params = req.body  
  const rt = await storeController.add(params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// 删除门店
router.post('/store-del',async (req,res)=>{
  const params = req.body  
  const rt = await storeController.delete(params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// 修改门店
router.post('/store-update',async (req,res)=>{
  const {id,params} = req.body  
  const rt = await storeController.updateById(id,params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// **********************门店管理 end********************************************

// **********************产品管理 start********************************************
// 产品列表
router.post('/product-list',async (req,res)=>{
  const {params,page} = resolveParams(req.body) // 解析参数
  let sort = null
  if(req.body.sort){
    sort = req.body.sort
    delete params.sort
  }else{
    sort={createTime:-1}
  }
  if(req.body.name){
      delete params.name
      params['$or'] = [ //多条件模糊查询，数组
          { name: { $regex: req.body.name, $options: 'i' } }
      ]
  }
  const populate = [
      {
          path:'series',
          //select:{nickname:1,avatar:1}
      },
  ]
  const rt = await productController.getList({params,page,populate,sort})
  
  if(!rt) return backErr(res,'获取数据失败')
  backSuc(res,rt)
})
// 获取产品列表，安系列（型号分类）
router.post('/product-serie-list',async (req,res)=>{
  const {params,page} = resolveParams(req.body) // 解析参数
  const sort = {createTime:-1}
  if(params.serieId){
      params.serieId = mongoose.Types.ObjectId(params.serieId)
  }
  if(req.body.name){
      delete params.name
      params['$or'] = [ //多条件模糊查询，数组
          { name: { $regex: req.body.name, $options: 'i' } }
      ]
  }
  let pm = [
      {
          $lookup:{
              from: 'products',// 关联产品表
              localField: "_id",//本表需要关联的字段
              foreignField: "series",//被连接表需要关联的字段
              as: "children"//查询出的结果集别名
          }
      },
      {
          $match:params
      }
  ]
  const rt = await serieController.getList2(pm,page,sort)
  if(!rt) return backErr(res,'获取数据失败')
  backSuc(res,rt)
})

// 添加产品（包括型号）
router.post('/product-add',async (req,res)=>{
  const params = req.body
  if(params.addSerieData && params.addSerieData.length>0){ // 新增型号/系列
    const rt1 = await serieController.add(params.addSerieData)
    if(!rt1){
      return backErr(res,'批量添加产品型号出错了') 
    }
    let ids = []  // 新增的型号id数组
    rt1.forEach(item =>{
      ids.push(item._id)
    })
    // 为需要新增的产品都添加上型号id
    params.subProducts.forEach(item =>{
      item.series = ids
    })
  }
  
  const rt = await productController.insertMany(params.subProducts)
  if(!rt) return backErr(res,'保存失败')

  backSuc(res,rt)
})
// 添加明细项目
router.post('/product-project-add',async (req,res)=>{
  const params = req.body  
  const rt = await productController.add(params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// 删除产品
router.post('/product-del',async (req,res)=>{
  const params = req.body  
  const rt = await productController.delete(params)
  if(!rt) return backErr(res,'保存失败')
  //await productController.remove({productId:params._id}) // 删除所有附加产品
  backSuc(res,rt)
})
// 修改产品
router.post('/product-update',async (req,res)=>{
  const {id,params} = req.body  
  const rt = await productController.updateById(id,params)
  if(!rt) return backErr(res,'保存失败')
  // if(params.type==1){ // 主产品
  //   if(params.subProducts && params.subProducts.length>0){
  //     // 先删除附加产品，然后在添加
  //     await productController.remove({productId:id})
  //     await productController.insertMany(params.subProducts.map(item =>({...item,productId:id})))
  //   }else{  // 不存在附加产品
  //     await productController.remove({productId:id})
  //   }
  // }
  
  backSuc(res,rt)
})
router.post('/serieAndProduct-update',async (req,res)=>{
  const params = req.body  
  if(params.updateSerieData){
    const rt = await serieController.updateById(params.updateSerieData.id,params.updateSerieData)
    if(!rt) return backErr(res,'产品型号更新出错了')
  }
  if(params.addProducts && params.addProducts.length>0){
    const rt = await productController.insertMany(params.addProducts)
    if(!rt) return backErr(res,'产品型号新增产品出错了')
  }
  if(params.delProducts && params.delProducts.length>0){
    let ids = []
    params.delProducts.forEach(item =>{
      ids.push(item._id)
    })
    //const rt = await productController.findOneAndUpdate({ _id: ids[0] },{ $pull: { series: params.updateSerieData.id} })
    const rt = await productController.update({ _id: ids },{ $pull: { series: params.updateSerieData.id} })
    if(!rt) return backErr(res,'从系列中删除产品失败')
  }
  backSuc(res,'参数错误')
})

// 从excel导入产品明细
router.post('/project-import-excel',async (req,res)=>{
  let saveDir = path.join(__dirname,'../../',UPLOADPATH)
  if(!fs.existsSync(saveDir)){ // 文件夹不存在，则创建
    const rt = fs.mkdirSync(saveDir) 
    if(rt){  // 创建失败
      console.log("创建文件夹失败")
      return backErr(res,'文件上传失败')
    }
  }

  const form = new multiparty.Form();
  form.encoding = 'utf-8';
  form.uploadDir =  saveDir // 设置上传存放路径
  form.parse(req, async (err, fields, files)=> {
      if(err){  // 上传失败
       return backErr(res,'文件上传失败')
      }else{
          const fpath = path.join(files.file[0].path) // 完整路径（保存的完整路径）
          // let fileObj = {
          //     name:files.file[0].originalFilename,
          //     url:LOCAL_IMG_URL+fpath.split('upload')[1],
          //     dir:fpath.split('upload')[1],
          //     size:files.file[0].size
          // }
          // backSuc(res,fileObj)

        // 获得上传的文件，开始获取表格数据
        //console.log("fpath：",fpath)
        
        const excelData = await importExcel(fpath)
        if(!excelData || !excelData[0].data || excelData[0].data.length<1){
            return backErr(res,'没有数据')
        }
        fs.unlinkSync(fpath);  // 删除文件
        const lists = excelData[0].data  // 二维码数组
        //console.log("数据：",lists)
        let objArr = []
        for(let i=0;i<lists.length;i++){
          if(i==0) continue;  // 从i=1开始，因为第一个元素是标题
          const arrItem = lists[i]
          if(!arrItem[0]) continue;  // 名称不存在，直接进入下次循环
          let obj = {
            name:arrItem[0],
            price:arrItem[1],
            unit:getUnitVal(arrItem[2]),
            unitName:arrItem[2],
            total:arrItem[3],
            discount:arrItem[4]
          }
          objArr.push(obj)
        }
        //console.log("获取结果：",objArr)
        const rt = await productController.insertMany(objArr)
        if(!rt) return backErr(res,'保存失败')

        backSuc(res,rt)
      }  
      
  })
})
// **********************产品管理 end********************************************

// **********************客户管理 start********************************************
// 客户列表
router.post('/custom-list',async (req,res)=>{
  const {params,page} = resolveParams(req.body) // 解析参数
  const sort = {createTime:-1}
  if(req.body.name){
      delete params.name
      params['$or'] = [ //多条件模糊查询，数组
          { name: { $regex: req.body.name, $options: 'i' } }
      ]
  }
  const rt = await customController.getList({params,page,sort})
  if(!rt) return backErr(res,'获取数据失败')
  backSuc(res,rt)
})

// 添加客户
router.post('/custom-add',async (req,res)=>{
  const params = req.body  
  const rt = await customController.add(params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// 删除客户
router.post('/custom-del',async (req,res)=>{
  const params = req.body  
  const rt = await customController.delete(params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// 修改客户
router.post('/custom-update',async (req,res)=>{
  const {id,params} = req.body  
  const rt = await customController.updateById(id,params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// **********************客户管理 end********************************************

// **********************系列管理 start********************************************
// 系列列表
router.post('/serie-list',async (req,res)=>{
  const {params,page} = resolveParams(req.body) // 解析参数
  const sort = {createTime:-1}
  if(req.body.name){
      delete params.name
      params['$or'] = [ //多条件模糊查询，数组
          { name: { $regex: req.body.name, $options: 'i' } }
      ]
  }
  const rt = await serieController.getList({params,page,sort})
  if(!rt) return backErr(res,'获取数据失败')
  backSuc(res,rt)
})

// 添加系列
router.post('/serie-add',async (req,res)=>{
  const params = req.body  
  const rt = await serieController.add(params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// 删除系列
router.post('/serie-del',async (req,res)=>{
  const params = req.body  
  const rt = await serieController.delete(params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// 修改系列
router.post('/serie-update',async (req,res)=>{
  const {id,params} = req.body  
  const rt = await serieController.updateById(id,params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// **********************客户管理 end********************************************

// **********************订单管理 start********************************************
// 订单列表
router.post('/order-list',async (req,res)=>{
  const {params,page} = resolveParams(req.body) // 解析参数
  let sort = null
  if(params.sort){
    sort = params.sort
    delete params.sort
  }else{
    sort={createTime:-1}
  }
  if(req.body.name){
      delete params.name
      params['$or'] = [ //多条件模糊查询，数组
          { name: { $regex: req.body.name, $options: 'i' } }
      ]
  }
  if(params.startTime && params.endTime){
    params['$and'] = [
        {
            "createTime": {
                "$gte": params.startTime//'2021-08-18 00:00:00'
            }
        }, {
            "createTime": {
                "$lte": params.endTime//'2021-08-18 23:00:00'
            }
        }
    ]
    delete params.startTime
    delete params.endTime
}
  const populate = [
      {
          path:'storeId',
      },
      {
          path:'customId',
      },
      {
        path:'create_user',
      },
      {
        path:'examine_user',
      },
      {
        path:'cashbackId'
      }
  ]
  const rt = await orderController.getList({params,page,sort,populate})
  if(!rt) return backErr(res,'获取数据失败')
  backSuc(res,rt)
})
// 添加
router.post('/order-add',async (req,res)=>{
  const params = req.body 
  // 为每个型号数据加一个id
  params.products.forEach((item,index)=>{
    item.id = new mongoose.Types.ObjectId()+"_"+index // 生成一个新的ObjectId(因为ObjectId可能有重复，所以把index加上)
  })
  const rt = await orderController.add(params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// 删除
router.post('/order-del',async (req,res)=>{
  const params = req.body  
  const rt = await orderController.delete(params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// 修改
router.post('/order-update',async (req,res)=>{
  const {id,params} = req.body  
  // 为每个型号数据加一个id
  params.products.forEach((item,index)=>{
    if(!item.id){
      item.id = new mongoose.Types.ObjectId()+"_"+index // 生成一个新的ObjectId(因为ObjectId可能有重复，所以把index加上)
    } 
  })
  const rt = await orderController.updateById(id,params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// **********************订单管理 end********************************************
























// **********************返款管理 start********************************************
// 列表
router.post('/cashback-list',async (req,res)=>{
  const {params,page} = resolveParams(req.body) // 解析参数
  let sort = null
  if(params.sort){
    sort = params.sort
    delete params.sort
  }else{
    sort={createTime:-1}
  }
  if(req.body.name){
      delete params.name
      params['$or'] = [ //多条件模糊查询，数组
          { name: { $regex: req.body.name, $options: 'i' } }
      ]
  }
  const populate = [
      {
          path:'stores',
      },
  ]
  const rt = await cashbackController.getList({params,page,sort,populate})
  if(!rt) return backErr(res,'获取数据失败')
  backSuc(res,rt)
})
// 添加
router.post('/cashback-add',async (req,res)=>{
  const params = req.body  
  const rt = await cashbackController.add(params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// 删除
router.post('/cashback-del',async (req,res)=>{
  const params = req.body  
  const rt = await cashbackController.delete(params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// 修改
router.post('/cashback-update',async (req,res)=>{
  const {id,params} = req.body  
  const rt = await cashbackController.updateById(id,params)
  if(!rt) return backErr(res,'保存失败')
  backSuc(res,rt)
})
// **********************返款管理 end********************************************











module.exports = router;